package com.gzsxy.excel.log.aspect;

import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import com.gzsxy.excel.entity.SysLog;
import com.gzsxy.excel.log.annotation.OperateLog;
import com.gzsxy.excel.log.event.SysLogEvent;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @Description: 异步日志入库
 * @Author: xiaolong
 * @date: 2022/3/30 8:56
 * @Version: 1.0
 */
@Aspect
@Slf4j
public class SysLogAspect {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    /**
     * @Description:  * 若不使用@SneakyThrows注解，newInsstance方法会要求抛出InstantiationException,
     *  * IllegalAccessException异常，且调用sneakyThrowsTest()的地方需要捕获这些异常，
     *  * 加上@SneakyThrows注解之后就不需要捕获异常信息。
     * @param:
     * @return:
    */
    @Around("@annotation(operateLog)")
    @SneakyThrows
    public Object around(ProceedingJoinPoint point, OperateLog operateLog){
        //注解类名
        String strClassName = point.getTarget().getClass().getName();
        ////方法名
        String strMethodName = point.getSignature().getName();
        log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);

        SysLog logVo = this.getSysLog();
        logVo.setTitle(operateLog.value());

        // 发送异步日志事件
        Long startTime = System.currentTimeMillis();
        Object obj;
        try {
            obj = point.proceed();
            //获取用户信息
//            if ("/auth/login".equals(logVo.getRequestUri())){
//                UserLoginInfoVo user = CurrentUserUtil.getUser();
//                if (null != user){
//                    logVo.setCreateUser(user.getId());
//                    logVo.setUpdateUser(user.getId());
//                }
//            }
        } catch (Exception e) {
            logVo.setException(e.getMessage());
            throw e;
        } finally {
            Long endTime = System.currentTimeMillis();
            logVo.setTime(endTime - startTime);
            eventPublisher.publishEvent(new SysLogEvent(logVo));
        }

        return obj;
    }


    public SysLog getSysLog() {
        HttpServletRequest request = ((ServletRequestAttributes) Objects
                .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        SysLog sysLog = new SysLog();
//        String userId = getUserId();
//        sysLog.setCreateUser(userId);
//        sysLog.setUpdateUser(userId);
        sysLog.setRemoteAddr(ServletUtil.getClientIP(request));
        sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
        sysLog.setMethod(request.getMethod());
        sysLog.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
        sysLog.setParams(HttpUtil.toParams(request.getParameterMap()));
        return sysLog;
    }

    //获取当前用户
//    private String getUserId() {
//        UserLoginInfoVo user = CurrentUserUtil.getUser();
//        if (null == user) {
//            return "none";
//        }
//
//        return user.getId();
//    }
}
